package pacman.brains;

import java.util.Hashtable;

import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Vector2f;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.util.pathfinding.Path;
import org.newdawn.slick.util.pathfinding.Path.Step;

import pacman.actors.Brain;
import pacman.map.Map;

public class BlueGhostBrain implements Brain {
    private static final int THINKINTIME = 50;			//Thời gian tính toán 50ms
    private static final float DISTANCE = 1;			//
    private static final int DISTANCE_PLAYER = 5;
    private int updateThinkingTime;
    private int updatePlayerPositionTime;
    private int currentStepIndex;
    private Path path;
    private Image dot;
    private Vector2f current;
    private Map map;
    private boolean cannotFindPath;

    private Vector2f a = null;
    private Vector2f b = null;
    private Vector2f c = null;
    private Vector2f d = null;

    public BlueGhostBrain(Map map, Vector2f start) throws SlickException {
		this.map = map;
		this.current = start;
		init();
    }

    public void init() {
		Hashtable<String, Vector2f> points = map.getBluePoint();
		if (points != null) {
		    a = points.get("a");
		    b = points.get("b");
		    c = points.get("c");
		    d = points.get("d");
		}
	
		path = null;
		updateThinkingTime = 0;
		updatePlayerPositionTime = 0;
		currentStepIndex = 0;
		cannotFindPath = false;
	
		try {
		    dot = new Image("data/bluedot.gif");
		} catch (Exception e) {
			System.out.println(e.getMessage());
	    }
		updatePathToPlayer();
    }

    public void update(int delta) {
		if (path == null) {
		    updatePathToPlayer();
		    return;
		}
		updateThinkingTime = updateThinkingTime + delta;
		if (updateThinkingTime > THINKINTIME) {
		    updateThinkingTime = 0;
		    if (currentStepIndex > path.getLength() - 1) {
		    	reThink(current, map, path);
		    }
		}
		updatePlayerPositionTime = updatePlayerPositionTime + delta;
    }

    private void reThink(Vector2f current, Map map, Path path) {
		currentStepIndex = 0;
		path = null;
		updatePathToPlayer();
    }

    private void updatePathToPlayer() {
		Vector2f target = null;
	
		if (current.distance(a) < DISTANCE) target = b;
		if (current.distance(b) < DISTANCE) target = c;
		if (current.distance(c) < DISTANCE) target = d;
		if (current.distance(d) < DISTANCE) target = a;
		if (target == null) target = a;
		if (Map.getPlayer().getPosition().distance(current) < DISTANCE_PLAYER*map.getTileSize()) {
		    target = Map.getPlayer().getPosition();
		}
		try {
		    path = map.getUpdatedPath((int) current.getX() / map.getTileSize(),
			    (int) current.getY() / map.getTileSize(), (int) target
				    .getX()
				    / map.getTileSize(), (int) target.getY()
				    / map.getTileSize());
		} catch (NullPointerException e) {
		    path = null;
		    cannotFindPath = true;
		}
    }

    public void render(BasicGameState game, Graphics g) {
		if (path != null) {
		    for (int i = 0; i < path.getLength(); i++) {
			Step a = path.getStep(i);
			dot.draw(a.getX() * map.getTileSize(), a.getY()
				* map.getTileSize());
		    }
		}
    }

    public Step getCurrentStep() {
		if (path == null) updatePathToPlayer();
		return path.getStep(currentStepIndex);
    }

    public void goToNextStep(Vector2f position) {
    	this.currentStepIndex++;
    	this.current = position;
    }

    public boolean isCannotFindPath() {
    	return cannotFindPath;
    }

    public void setCurrent(Vector2f current) {
    	this.current = current;
    }

}
